/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bff.mpd.musicjukebox.ui.components;

import com.bff.bjj.ui.component.MusicList;
import com.bff.mpd.musicjukebox.lib.AllAlbum;
import com.bff.mpd.musicjukebox.lib.JukeboxProperties;
import com.bff.mpd.musicjukebox.lib.MusicObjects;
import com.bff.mpd.musicjukebox.lib.actions.PlaylistInsertAlbumAction;
import com.bff.mpd.utils.MPDComparator;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import org.bff.javampd.MPDDatabase;
import org.bff.javampd.MPDPlaylist;
import org.bff.javampd.objects.MPDAlbum;
import org.bff.javampd.objects.MPDArtist;
import org.bff.javampd.objects.MPDGenre;

/**
 *
 * @author bfindeisen
 */
public class AlbumList extends MusicList implements MouseListener {

    private MPDDatabase database;
    private DefaultListModel albumListModel;
    private MPDPlaylist playlist;
    private JPopupMenu albumMenu;
    private AlbumListCellRenderer albumListCellRenderer;
    private ListType type;
    private AllAlbum allAlbumYear;
    private AllAlbum allAlbumGenre;
    private AllAlbum allAlbumArtist;
    private MPDArtist artist;
    private boolean loading;
    private static MPDComparator mpdComparator;

    /**
     * @return the artist
     */
    public MPDArtist getArtist() {
        return artist;
    }

    public enum ListType {

        ARTIST, GENRE, YEAR
    }

    public AlbumList() {
        playlist = JukeboxProperties.getInstance().getPlaylist();

        mpdComparator = new MPDComparator();

        albumListModel = new DefaultListModel();
        this.database = JukeboxProperties.getInstance().getDatabase();

        allAlbumYear = new AllAlbum(ListType.YEAR);
        allAlbumGenre = new AllAlbum(ListType.GENRE);
        allAlbumArtist = new AllAlbum(ListType.ARTIST);

        this.albumListCellRenderer = new AlbumListCellRenderer();
        setCellRenderer(this.albumListCellRenderer);

        addMouseListener(this);
    }

    public void setType(ListType type) {
        this.type = type;
    }

    public ListType getType() {
        return type;
    }

    public void setArtist(MPDArtist artist) {
        setType(ListType.ARTIST);
        this.artist = artist;
        listAlbums(artist);
    }

    public void setYear(String year) {
        setType(ListType.YEAR);
        listAlbums(year);
    }

    public void setGenre(MPDGenre genre) {
        setType(ListType.GENRE);
        listAlbums(genre);
    }

    public void setAlbums(Collection<MPDAlbum> albums) {
        try {
            albumListModel.clear();
            for (MPDAlbum album : albums) {
                albumListModel.addElement(album);
            }

            setModel(albumListModel);
            setSelectedIndex(0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void listAlbums(String year) {
        if (!isLoading()) {
            List<MPDAlbum> albumList = null;
            try {
                albumListModel.clear();
                albumListModel.addElement(allAlbumYear);
                albumList = new ArrayList<MPDAlbum>(getDatabase().listAlbumsByYear(year));

                Collections.sort(albumList, mpdComparator);

                for (MPDAlbum album : albumList) {
                    albumListModel.addElement(album);
                }

                setModel(albumListModel);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                setLoading(false);
            }
        }
    }

    private void listAlbums(MPDArtist artist) {
        if (!isLoading()) {
            List<MPDAlbum> albumList = null;
            try {
                setLoading(true);
                albumListModel.clear();
                albumListModel.addElement(allAlbumArtist);
                albumList = new ArrayList<MPDAlbum>(getDatabase().listAlbumsByArtist(artist));

                Collections.sort(albumList, mpdComparator);

                for (MPDAlbum album : albumList) {
                    albumListModel.addElement(album);
                }

                setModel(albumListModel);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                setLoading(false);
            }
        }
    }

    private void listAlbums(MPDGenre genre) {
        if (!isLoading()) {
            List<MPDAlbum> albumList = null;
            try {
                albumListModel.clear();
                albumListModel.addElement(allAlbumGenre);
                albumList = new ArrayList<MPDAlbum>(getDatabase().listAlbumsByGenre(genre));

                Collections.sort(albumList, mpdComparator);

                for (MPDAlbum album : albumList) {
                    albumListModel.addElement(album);
                }

                setModel(albumListModel);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                setLoading(false);
            }
        }
    }

    public void listAll() {
        List<MPDAlbum> albumList = null;
        try {
            albumListModel.clear();
            albumList = new ArrayList<MPDAlbum>(MusicObjects.getAlbums());

            Collections.sort(albumList, mpdComparator);

            for (MPDAlbum album : albumList) {
                albumListModel.addElement(album);
            }

            setModel(albumListModel);
            setSelectedIndex(0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public MPDAlbum getSelectedAlbum() {
        return (MPDAlbum) getSelectedValue();
    }

    public MPDDatabase getDatabase() {
        return database;
    }

    public void setDatabase(MPDDatabase database) {
        this.database = database;
    }

    private void createAlbumPlayPopUp(MouseEvent e) {
        if (e.isPopupTrigger()) {
            setSelectedIndex(locationToIndex(e.getPoint()));
            MPDAlbum album = getSelectedAlbum();
            albumMenu = new JPopupMenu();
            albumMenu.add(new JMenuItem(new PlaylistInsertAlbumAction(getPlaylist(), album, getArtist())));
            albumMenu.setVisible(true);
            albumMenu.show(e.getComponent(), e.getX(), e.getY());
        }
    }

    public MPDPlaylist getPlaylist() {
        return playlist;
    }

    public void setPlaylist(MPDPlaylist playlist) {
        this.playlist = playlist;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() == 2) {
//            MPDAlbum album = getSelectedAlbum();
//            new AlbumThumbnailDialog(Utils.getParentComponent(this), album).setVisible(true);
        } else {
            createAlbumPlayPopUp(e);
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        createAlbumPlayPopUp(e);
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        createAlbumPlayPopUp(e);
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mouseExited(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     * @return the albumListCellRenderer
     */
    public AlbumListCellRenderer getAlbumListCellRenderer() {
        return albumListCellRenderer;
    }

    /**
     * @param albumListCellRenderer the albumListCellRenderer to set
     */
    public void setAlbumListCellRenderer(AlbumListCellRenderer albumListCellRenderer) {
        this.albumListCellRenderer = albumListCellRenderer;
    }

    /**
     * @return the loading
     */
    public boolean isLoading() {
        return loading;
    }

    /**
     * @param loading the loading to set
     */
    public void setLoading(boolean loading) {
        this.loading = loading;
    }

    public void clear() {
        albumListModel.clear();
    }
}
